package imp

import (
	sqlc "bgs/db/sqlc"
	activityGrpc "bgs/grpc/gen/service/activity"
	// commonActivityGrpc "bgs/grpc/gen/shared/common_activity"
	"bgs/grpc/gen/shared/message"
	activityService "bgs/service/activity"
	"bgs/service/model"
	"bgs/util"
	"fmt"

	"context"
	"database/sql"
)

/****************************************************************************************/
/*                               spokesman activity entity of helper                    */
/****************************************************************************************/

func transformActivityOfSEntityToPb(
	activityProductWithProductInfos []sqlc.ListNormalActivityProductWithProductInfosByActivityIDRow,
	activitySkuWithProductOrProductSpecInfos []*model.ActivitySkuWithProductOrProductSpecInfo,
	// activityConsignment sqlc.ActivityConsignment,
	// activityConsignmentBonusSettings []sqlc.ActivityConsignmentBonusSetting
) func(sqlc.Activity) *activityGrpc.ActivityOfSEntity {
	return func(o sqlc.Activity) *activityGrpc.ActivityOfSEntity {
		return &activityGrpc.ActivityOfSEntity{
			Id:                      o.ID,
			BrandId:                 o.BrandID,
			Name:                    o.Name,
			Type:                    o.Type,
			Intro:                   string(o.Intro),
			ProcessStatus:           o.ProcessStatus,
			Published:               sqlc.GoNTimeToPBTimestamp(o.Published),
			Begined:                 sqlc.GoTimeToPBTimestamp(o.Begined),
			Ended:                   sqlc.GoTimeToPBTimestamp(o.Ended),
			TimeRanges:              transformTimeRangeEntityToPb(o.TimeRanges),
			Background:              o.Background.String,
			Poster:                  o.Poster.String,
			SaleMode:                o.SaleMode,
			VerifyQualification:     o.VerifyQualification,
			QualifyTypes:            o.QualifyTypes,
			DeliveryModes:           o.DeliveryModes,
			SpokesmanId:             o.SpokesmanID.Int64,
			MaxiumPurchaseFrequency: o.MaxiumPurchaseFrequency.Int32,
			MinimumPurchaseAmount:   o.MinimumPurchaseAmount,
			Tel:                     o.Tel,
			Owner:                   o.Owner,
			RootId:                  o.RootID.Int64,
			ParentId:                o.ParentID.Int64,
			ActivityProductWithSkus: mapActivityProductWithProductInfoToPb(activityProductWithProductInfos, activitySkuWithProductOrProductSpecInfos, transActivityProductWithProductInfoToPb),
			// Consignment:             transActivityConfignmentToPb(activityConsignment, activityConsignmentBonusSettings),
		}
	}
}

/****************************************************************************************/
/*                               spokesman activity entity of cmd                       */
/****************************************************************************************/

// CreateActivityOfS S新增活动
func (s *ActivityAPIService) EndorseActivityByS(ctx context.Context, req *activityGrpc.EndorseActivityBySRequest) (res *activityGrpc.EndorseActivityBySResponse, err error) {
	slog := s.NewContextLogger(ctx)
	slog.Infof("activitySpokesman->EndorseActivityByS:%v", req)
	res = &activityGrpc.EndorseActivityBySResponse{
		OpRet: &message.OperationResult{
			Success: true,
			Code:    0,
		},
	}

	userID := req.UserId
	rawActivityID := req.ActivityId

	var activity sqlc.Activity
	var activityProductWithProductInfos []sqlc.ListNormalActivityProductWithProductInfosByActivityIDRow
	var activitySkuWithProductOrProductSpecInfos []*model.ActivitySkuWithProductOrProductSpecInfo

	err = s.dao.NewTxRunner().SqlcExecTx(ctx, func(q *sqlc.Queries) (err error) {

		rawActivity, err := q.GetActivity(ctx, rawActivityID)
		if err != nil {
			if sql.ErrNoRows == err {
				return fmt.Errorf("无法找到代言的活动:%d", rawActivityID)
			}
			return err
		}
		brandID := rawActivity.BrandID
		NParentID := sqlc.NInt64FromInt64(rawActivityID)
		rawActivityOwner := rawActivity.Owner

		if rawActivityOwner == string(sqlc.EmActivityOwnerSpokesman) {
			err = fmt.Errorf("活动owner不匹配")
			return
		}
		if rawActivity.ProcessStatus != string(sqlc.EmActivityProcessStatusProcessing) {
			res.OpRet = &message.OperationResult{
				Success: false,
				Code:    400,
				Msg:     fmt.Sprintf("代言的活动[%s]状态不允许", rawActivity.ProcessStatus),
			}
			return
		}

		var spokesmanPtr *sqlc.Spokesman
		if rawActivityOwner == string(sqlc.EmActivityOwnerBrand) {
			spokesmanPtr, err = s.spokesmanService.GetBrandSpokesmanPtr(ctx, q, userID, brandID)
			if err != nil {
				return
			}
		} else {
			if !rawActivity.StoreID.Valid {
				err = fmt.Errorf("owner与数据不一致")
				return
			}
			spokesmanPtr, err = s.spokesmanService.GetStoreSpokesmanPtr(ctx, q, userID, rawActivity.StoreID.Int64)
			if err != nil {
				return
			}
		}
		spokesmanID := spokesmanPtr.ID

		activity, err = q.CreateActivity(ctx, sqlc.CreateActivityParams{
			BrandID:                       brandID,
			StoreID:                       rawActivity.StoreID,
			DistributorID:                 rawActivity.DistributorID,
			SpokesmanID:                   sqlc.NInt64FromInt64(spokesmanID),
			PubUserID:                     userID,
			Name:                          rawActivity.Name,
			Type:                          rawActivity.Type,
			Intro:                         rawActivity.Intro,
			Begined:                       rawActivity.Begined,
			Ended:                         rawActivity.Ended,
			Background:                    rawActivity.Background,
			SaleMode:                      rawActivity.SaleMode,
			DeliveryModes:                 rawActivity.DeliveryModes,
			IsUseWarehouseShippingFeeRule: rawActivity.IsUseWarehouseShippingFeeRule,
			UnifiedShippingFee:            rawActivity.UnifiedShippingFee,
			MaxiumPurchaseFrequency:       rawActivity.MaxiumPurchaseFrequency,
			MinimumPurchaseAmount:         rawActivity.MinimumPurchaseAmount,
			Tel:                           rawActivity.Tel,
			RootID:                        NParentID, // 目前root_id==parent_id
			ParentID:                      NParentID,
			Owner:                         string(sqlc.EmActivityOwnerSpokesman),
		})
		if err != nil {
			return err
		}
		slog.Infof("1 创建代言活动S ok")

		// 活动S仓库
		slog.Infof("2 代言仓库直接读取代言的活动,略过 ok")

		// 活动商品、商品规格
		normalParentActivityProducts, err := q.ListNormalActivityProductsByActivityID(ctx, rawActivityID)
		if err != nil {
			return err
		}

		normalParentActivitySkus, err := q.ListNormalActivitySkusByActivityID(ctx, rawActivityID)
		if err != nil {
			return err
		}

		var activityProduct sqlc.ActivityProduct
		for _, item1 := range normalParentActivityProducts {
			quantity := util.Int32IfThenElse(item1.Quantity == 0, 1, item1.Quantity)
			activityProduct, err = q.UpsertActivityProduct(ctx, sqlc.UpsertActivityProductParams{
				BrandID:          brandID,
				ActivityID:       activity.ID,
				RootActivityID:   NParentID, // 目前root_id==parent_id
				ParentActivityID: NParentID,
				ProductID:        item1.ProductID,
				IsShow:           true,
				PriceMin:         item1.PriceMin,
				PriceMax:         item1.PriceMax,
				Quantity:         quantity,
				SortNo:           item1.SortNo,
			})
			if err != nil {
				return err
			}

			var skusOfCurrentActivityProduct []sqlc.ActivitySku
			skusFiltered := util.Filter(util.ToGenericSlice(normalParentActivitySkus), func(v interface{}) bool {
				val := v.(sqlc.ActivitySku)
				return val.ProductID == item1.ProductID
			})

			for _, v := range skusFiltered {
				skusOfCurrentActivityProduct = append(skusOfCurrentActivityProduct, v.(sqlc.ActivitySku))
			}

			for _, item2 := range skusOfCurrentActivityProduct {
				_, err = q.UpsertActivitySku(ctx, sqlc.UpsertActivitySkuParams{
					BrandID:           brandID,
					ActivityID:        activity.ID,
					RootActivityID:    NParentID, // 目前root_id==parent_id
					ParentActivityID:  NParentID,
					ActivityProductID: activityProduct.ID,
					ProductID:         item2.ProductID,
					ProductSpecID:     item2.ProductSpecID,
					Price:             item2.Price,
					Maximum:           0, // 0代表这是个活动最大可售数量为0,一般是代言的活动
					ProductSpecKey:    fmt.Sprintf("%d-%d", item2.ProductID, item2.ProductSpecID.Int64),
					StorageKey:        item2.StorageKey,
					SortNo:            item2.SortNo,
				})
				if err != nil {
					return err
				}
			}

		}
		slog.Infof("3 设置代言活动S商品、商品规格 ok")

		activityProductWithProductInfos, activitySkuWithProductOrProductSpecInfos, err = s.activityService.FetchNormalProductAndSkus(ctx, q, activity.ID)
		if err != nil {
			return err
		}
		slog.Info("5 读取活动s sku及产品规格信息 ok")

		_, err = s.activityService.PublishActivity(ctx, q, activityService.PublishActivityParam{
			ActivityPtr: &activity,
			UserID:      userID,
		})
		if err != nil {
			return err
		}
		slog.Infof("6 发布代言活动 ok")

		err = s.userService.UpdateUserStatSinceActivityEndorsed(ctx, q, userID)
		if err != nil {
			return err
		}
		slog.Infof("7 发布代言活动后更新到(UserStat) ok")

		err = s.spokesmanService.UpdateEndorseActivityCountSinceActivityPublished(ctx, q, &activity)
		if err != nil {
			return err
		}
		slog.Infof("8 发布代言活动后更新到(Spokesman) ok")
		return
	})

	if err != nil {
		res.OpRet = &message.OperationResult{
			Success: false,
			Code:    400,
			Msg:     err.Error(),
		}
		return
	}
	res.ActivityOfS = transformActivityOfSEntityToPb(activityProductWithProductInfos, activitySkuWithProductOrProductSpecInfos)(activity)
	return
}

/****************************************************************************************/
/*                      spokesman activity entity of query                              */
/****************************************************************************************/

// GetActivityOfS 获取单个代言活动S
func (s *ActivityAPIService) GetActivityOfS(ctx context.Context, req *activityGrpc.GetActivityOfSRequest) (res *activityGrpc.GetActivityOfSResponse, err error) {
	slog := s.NewContextLogger(ctx)
	slog.Infof("activityImp->GetActivityOfS:%v", req)
	res = &activityGrpc.GetActivityOfSResponse{
		OpRet: &message.OperationResult{
			Success: true,
			Code:    0,
		},
	}
	q := s.dao.Q

	activity, err := q.GetActivity(ctx, req.Id)
	if err != nil {
		res.OpRet = &message.OperationResult{
			Success: false,
			Code:    400,
			Msg:     err.Error(),
		}
		return
	}
	normalActivityProductWithProductInfos, normalActivitySkus, err := s.activityService.FetchNormalProductAndSkus(ctx, q, activity.ID)
	if err != nil {
		res.OpRet = &message.OperationResult{
			Success: false,
			Code:    400,
			Msg:     err.Error(),
		}
		return
	}

	// activityConsignment, normalActivityConsignmentBonusSettings, err := s.activityService.FetchConsignmentAndConsignmentBonusSettings(ctx, q, activity.ParentID.Int64)
	// if err != nil {
	// 	res.OpRet = &message.OperationResult{
	// 		Success: false,
	// 		Code:    400,
	// 		Msg:     err.Error(),
	// 	}
	// 	return
	// }

	// res.ActivityOfS = transformActivityOfSEntityToPb(normalActivityProductWithProductInfos, normalActivitySkus, activityConsignment, normalActivityConsignmentBonusSettings)(activity)
	res.ActivityOfS = transformActivityOfSEntityToPb(normalActivityProductWithProductInfos, normalActivitySkus)(activity)
	return
}

// GetActivityOfSByParentIDAndSpokesmanID 通过品牌活动id和代言人id获取单个代言活动S
func (s *ActivityAPIService) GetActivityOfSByParentIDAndSpokesmanID(ctx context.Context, req *activityGrpc.GetActivityOfSByParentIDAndSpokesmanIDRequest) (res *activityGrpc.GetActivityOfSByParentIDAndSpokesmanIDResponse, err error) {
	slog := s.NewContextLogger(ctx)
	slog.Infof("activityImp->GetActivityOfSByParentIDAndSpokesmanID:%v", req)
	res = &activityGrpc.GetActivityOfSByParentIDAndSpokesmanIDResponse{
		OpRet: &message.OperationResult{
			Success: true,
			Code:    0,
		},
	}

	q := s.dao.Q

	activity, sqlErr := q.GetActivityOfSByParentIDAndSpokesmanID(ctx, sqlc.GetActivityOfSByParentIDAndSpokesmanIDParams{
		ParentID:    sqlc.NInt64FromInt64(req.ParentId),
		SpokesmanID: sqlc.NInt64FromInt64(req.SpokesmanId),
	})
	if sqlErr != nil {
		res.OpRet = &message.OperationResult{
			Success: false,
			Code:    util.Int32IfThenElse(sql.ErrNoRows == sqlErr, 404, 400),
			Msg:     sqlErr.Error(),
		}
		return
	}

	normalActivityProductWithProductInfos, normalActivitySkus, err := s.activityService.FetchNormalProductAndSkus(ctx, q, activity.ID)
	if err != nil {
		res.OpRet = &message.OperationResult{
			Success: false,
			Code:    400,
			Msg:     err.Error(),
		}
		return
	}

	// activityConsignment, normalActivityConsignmentBonusSettings, err := s.activityService.FetchConsignmentAndConsignmentBonusSettings(ctx, q, activity.ParentID.Int64)
	// if err != nil {
	// 	res.OpRet = &message.OperationResult{
	// 		Success: false,
	// 		Code:    400,
	// 		Msg:     err.Error(),
	// 	}
	// 	return
	// }

	// res.ActivityOfS = transformActivityOfSEntityToPb(normalActivityProductWithProductInfos, normalActivitySkus, activityConsignment, normalActivityConsignmentBonusSettings)(activity)
	res.ActivityOfS = transformActivityOfSEntityToPb(normalActivityProductWithProductInfos, normalActivitySkus)(activity)
	return
}
